"""
Case Type   : 共享存储-系统内部工具-dsscmd
Case Name   : dsscmd工具设置配置项
Create At   : 2023/4/21
Owner       : opentestcase019
Description :
    1.设置配置项，查看帮助信息
    2.设置配置项，不指定参数
    3.设置配置项，指定-n name和-v value参数为有效值
    4.设置配置项，指定-n name参数为无效值
    5.设置配置项，指定-v value参数为无效值
    6.在dss关闭的情况下执行设置配置项
    7.在集群停止的情况下执行
    8.DSS_HOME路径权限不足时，设置配置项
    9.在备机设置配置项
    10.设置配置项，指定scope参数为有效值
    11.设置配置项，指定scope参数为无效值
    12.设置配置项，指定-U UDS:socket_domain参数为正常值
    13.设置配置项，指定指定错误的-U UDS:socket_domain参数和权限不足的socket_domain
Expect      :
    1.查看成功
    2.合理报错
    3.设置成功
    4.合理报错
    5.合理报错
    6.合理报错
    7.合理报错
    8.合理报错
    9.设置成功
    10.设置成功
    11.合理报错
    12.设置成功
    13.合理报错
History     :
"""
import os
import time
import re
import unittest
from yat.test import Node
from yat.test import macro
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant

Primary_SH = CommonSH('PrimaryDbUser')


@unittest.skipIf(1 == Primary_SH.get_node_num(), '单机环境不执行')
class ShareStorageTool(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.logger.info(f"-----{os.path.basename(__file__)} start-----")
        self.primary_node = Node('PrimaryDbUser')
        self.primary_sh = CommonSH('PrimaryDbUser')
        self.standby_node = Node('Standby1DbUser')
        self.common = Common()
        self.constant = Constant()
        self.dss_inst_path = os.path.join(macro.DSS_INSTANCE,
                                          'cfg', 'dss_inst.ini')
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
                      f"dsscmd getcfg -n _log_LEVEL;"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.default_level = execute_msg.split()[-1].strip('.')
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
                      f"dsscmd getcfg -n _LOG_BACKUP_FILE_COUNT;"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.default_count = execute_msg.split()[-1].strip('.')
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
                      f"dsscmd getcfg -n _LOG_MAX_FILE_SIZE;"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.default_size = execute_msg.split()[-1].strip('.')

    def test_sharestorage_tool(self):
        step1 = "-----step1:设置配置项，查看帮助信息;expect:查看成功-----"
        self.logger.info(step1)
        execute_cmd = f"source {macro.DB_ENV_PATH};dsscmd setcfg -h"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn('Usage:dsscmd setcfg <-n name> <-v value> [-s scope] '
                      '[-U UDS:socket_domain]\n[client command] set config '
                      'value by name\n-n/--name <name>, <required>, the config'
                      ' name to set\n-v/--value <value>, <required>, the value'
                      ' of the config name to set\n-s/--scope <scope>, '
                      '[optional], the scope to save the config\nscope '
                      'optional values: [memory | pfile | both]. default value'
                      ' is both\nMemory indicates that the modification is '
                      'made in memory and takes effect immediately;\nPfile '
                      'indicates that the modification is performed in the '
                      'pfile. \nThe database must be restarted for the '
                      'modification to take effect.\n-U/--UDS <UDS:'
                      'socket_domain>, [optional], the unix socket path of '
                      'dssserver, default value is UDS:$DSS_HOME/.'
                      'dss_unix_d_socket', execute_msg, "执行失败" + step1)

        step2 = "-----step2:设置配置项，不指定参数;expect:合理报错-----"
        self.logger.info(step2)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
                      f"dsscmd setcfg;"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn('args [-n|--name] needs input value.',
                      execute_msg, "执行失败" + step2)

        step3 = "-----step3:设置配置项，指定-n name和-v value参数为有效值;expect:设置成功-----"
        self.logger.info(step3)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            dsscmd setcfg -n _log_LEVEL -v 255 -s both;
            dsscmd setcfg --name _LOG_BACKUP_FILE_COUNT -v 128 -s both;
            dsscmd setcfg -n _LOG_MAX_FILE_SIZE --value 1G -s both;
            cat {self.dss_inst_path};'''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertEquals(3, execute_msg.count("Succeed to set cfg"),
                          "执行失败" + step3)
        self.assertIn('_LOG_LEVEL = 255', execute_msg, "执行失败" + step3)
        self.assertIn('_LOG_BACKUP_FILE_COUNT = 128',
                      execute_msg, "执行失败" + step3)
        self.assertIn('_LOG_MAX_FILE_SIZE = 1G', execute_msg,
                      "执行失败" + step3)

        step4 = "-----step4:设置配置项，指定-n name参数为无效值;expect:合理报错-----"
        self.logger.info(step4)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
        dsscmd setcfg -n _log_level参数 -v 255 -s both;
        dsscmd setcfg --name _LOG_BACKUP_FILE_COUNT_NOT_EXISTS -v 128 -s both;
        dsscmd setcfg -n _LOG_MAX_FILE_SIZE@#% --value 1G -s both'''
        self.logger.info(execute_cmd)
        res = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertEquals(2, res.count(
            "The name's letter should be [alpha|digit|-|_]"),
                          "执行失败" + step4)
        self.assertIn('Invalid name when set cfg.', res, "执行失败" + step4)

        step5 = "-----step5:设置配置项，指定-v value参数为无效值;expect:合理报错-----"
        self.logger.info(step5)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            dsscmd setcfg -n _log_level -v "-2" -s both;
            dsscmd setcfg --name _LOG_BACKUP_FILE_COUNT -v 5446 -s both;
            dsscmd setcfg -n _LOG_MAX_FILE_SIZE --value 5G -s both;'''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertEquals(3, execute_msg.count("Failed to set cfg"),
                          "执行失败" + step5)

        step6 = "-----step6:在dss关闭的情况下执行设置配置项;expect:合理报错-----"
        self.logger.info(step6)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            dsscmd stopdss;sleep 2;
            dsscmd setcfg -n _LOG_LEVEL -v 255 -s both;
            dsscmd setcfg --name _LOG_BACKUP_FILE_COUNT -v 128 -s both;
            dsscmd setcfg -n _LOG_MAX_FILE_SIZE --value 1G -s both'''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertEquals(3, execute_msg.count(
            self.constant.failed_to_get_uds_connection),
                          "执行失败" + step6)

        step7 = "-----step7:在dss关闭的情况下执行设置配置项;expect:合理报错-----"
        self.logger.info(step7)
        stop_msg = self.primary_sh.exec_cm_ctl(mode='stop')
        self.logger.info(stop_msg)
        self.assertIn(self.constant.cm_stop_success_msg,
                      stop_msg, '执行失败' + step6)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            dsscmd setcfg -n _LOG_LEVEL -v 255 -s both;
            dsscmd setcfg --name _LOG_BACKUP_FILE_COUNT -v 128 -s both;
            dsscmd setcfg -n _LOG_MAX_FILE_SIZE --value 1G -s both'''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertEquals(3, execute_msg.count(
            self.constant.failed_to_get_uds_connection),
                          "执行失败" + step7)
        start_msg = self.primary_sh.exec_cm_ctl(mode='start')
        self.logger.info(start_msg)
        self.assertIn(self.constant.cm_start_success_msg,
                      start_msg, '启动集群失败')
        time.sleep(30)
        status = self.primary_sh.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败')

        step8 = "-----step8:DSS_HOME路径权限不足时，设置dss节点的auid;expect:合理报错-----"
        self.logger.info(step8)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            chmod 000 {macro.DSS_INSTANCE};
            dsscmd setcfg -n _LOG_LEVEL -v 255 -s both;
            dsscmd setcfg --name _LOG_BACKUP_FILE_COUNT -v 128 -s both;
            dsscmd setcfg -n _LOG_MAX_FILE_SIZE --value 1G -s both
            chmod 700 {macro.DSS_INSTANCE};'''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertEquals(3, execute_msg.count(
            self.constant.failed_to_get_uds_connection), "执行失败" + step8)

        step9 = "-----step9:在备机设置配置项;expect:设置成功-----"
        self.logger.info(step9)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            dsscmd setcfg -n _LOG_LEVEL -v 255 -s both;
            dsscmd setcfg --name _LOG_BACKUP_FILE_COUNT -v 128 -s both;
            dsscmd setcfg -n _LOG_MAX_FILE_SIZE --value 1G -s both'''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.standby_node, execute_cmd)
        self.assertEquals(3, execute_msg.count("Succeed to set cfg"),
                          "执行失败" + step9)

        step10 = "-----step10:设置配置项，指定scope参数为有效值;expect:设置成功-----"
        self.logger.info(step10)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            dsscmd setcfg -n _log_LEVEL -v 556 -s memory;
            dsscmd getcfg -n _log_LEVEL;
            grep _LOG_LEVEL {self.dss_inst_path};'''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn('Succeed to set cfg, name is _log_LEVEL, value is 556.',
                      execute_msg, "执行失败" + step10)
        self.assertIn('Succeed to get cfg, name is _log_LEVEL, value is 556.',
                      execute_msg, "执行失败" + step10)
        self.assertIn('_LOG_LEVEL = 255', execute_msg, "执行失败" + step10)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            dsscmd setcfg -n _log_LEVEL -v 882 -s pfile;
            dsscmd getcfg -n _log_LEVEL;
            grep _LOG_LEVEL {self.dss_inst_path};'''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn('Succeed to set cfg, name is _log_LEVEL, value is 882.',
                      execute_msg, "执行失败" + step10)
        self.assertIn('Succeed to get cfg, name is _log_LEVEL, value is 556.',
                      execute_msg, "执行失败" + step10)
        self.assertIn('_LOG_LEVEL = 882', execute_msg, "执行失败" + step10)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            dsscmd setcfg -n _log_LEVEL -v 1025 -s both;
            dsscmd getcfg -n _log_LEVEL;
            grep _LOG_LEVEL {self.dss_inst_path};'''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn('Succeed to set cfg, name is _log_LEVEL, value is 1025.',
                      execute_msg, "执行失败" + step10)
        self.assertIn('Succeed to get cfg, name is _log_LEVEL, value is 1025.',
                      execute_msg, "执行失败" + step10)
        self.assertIn('_LOG_LEVEL = 1025', execute_msg, "执行失败" + step10)

        step11 = "-----step11:设置配置项，指定scope参数为有效值;expect:设置成功-----"
        self.logger.info(step11)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            dsscmd setcfg -n _log_LEVEL -v 556 -s aaa;
            dsscmd setcfg -n _log_LEVEL -v 556 -s 111;
            dsscmd setcfg -n _log_LEVEL -v 556 -s @#$'''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertEquals(3, execute_msg.count(
            "scope should be [memory | pfile | both]."), "执行失败" + step11)

        step12 = "-----step12:设置配置项，指定-U UDS:socket_domain参数为正常值;" \
                 "expect:设置成功-----"
        self.logger.info(step12)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            dsscmd setcfg -n _log_LEVEL -v 255 -s both -U {macro.UDS_PATH};
            dsscmd getcfg -n _log_LEVEL'''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn('Succeed to set cfg, name is _log_LEVEL, value is 255.\n'
                      'Succeed to get cfg, name is _log_LEVEL, value is 255.',
                      execute_msg, "执行失败" + step12)

        step13 = "-----step13:设置配置项，指定指定错误的-U UDS:socket_domain" \
                 "参数和权限不足的socket_domain;expect:合理报错-----"
        self.logger.info(step13)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
        dsscmd setcfg -n _log_LEVEL -v 1025 -s both -U {macro.UDS_PATH}.cfg;
        chmod 000 {macro.UDS_PATH[4::]};
        dsscmd setcfg -n _log_LEVEL -v 1025 -s both -U {macro.UDS_PATH};
        chmod 600 {macro.UDS_PATH[4::]};'''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertEquals(2, execute_msg.count(
            self.constant.failed_to_get_uds_connection), "执行失败" + step13)

    def tearDown(self):
        self.logger.info("-----集群状态-----")
        status = self.primary_sh.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        self.logger.info("-----恢复参数-----")
        cmd = f'source {macro.DB_ENV_PATH};' \
              f'dsscmd setcfg -n _LOG_LEVEL -v {self.default_level} -s both;' \
              f'dsscmd setcfg --name _LOG_BACKUP_FILE_COUNT -v ' \
              f'{self.default_count} -s both;' \
              f'dsscmd setcfg -n _LOG_MAX_FILE_SIZE --value ' \
              f'{self.default_size} -s both'
        self.logger.info(cmd)
        res = self.common.get_sh_result(self.standby_node, cmd)
        self.assertEquals(3, res.count("Succeed to set cfg"),
                          "恢复参数失败")
        self.logger.info(f"-----{os.path.basename(__file__)} end-----")
